package com.l.web.master.system.webnode;

import org.bson.types.ObjectId;
import org.l.qiao.Cluster;
import org.l.qiao.builder.Field;
import org.l.qiao.builder.Query;
import org.l.qiao.builder.Sort;
import org.l.qiao.builder.Update;
import org.l.qiao.web.KeyUpdate;
import com.l.web.common.ResponseCode;
import com.l.web.common.ResponseInfo;
import com.l.web.util.ServiceSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class WebNodeService extends ServiceSupport {
    @Autowired
    private WebNodeDAO webNodeDAO;

    public List getList(Cluster sort) {
        List webNodes = webNodeDAO.find(null, null, sort);
        return webNodes;
    }

    public Cluster detail(String id, Map modelMap) {
        Cluster webNode = webNodeDAO.findById(id);
        return webNode;
    }

    public List findParents(Cluster webNode) {
        Query query = new Query();
        query.in(WebNode.ID, webNode.getList(WebNode.PARENT, new ArrayList()));
        Field field = new Field(WebNode.NAME);
        Sort sort = new Sort();
        sort.asc(WebNode.DEEP);
        List parents = webNodeDAO.find(query, field, sort);
        return parents;
    }

    public int save(WebNode webNode) {
        ResponseInfo rj = new ResponseInfo();
        String parentid = webNode.getString(WebNode.PARENT_ID, "");
        List parent;

        if (parentid == null || "".equals(parentid)) {
            parent = new ArrayList();
            webNode.remove(WebNode.PARENT_ID);
        } else {
            Cluster cluster = webNodeDAO.findById(parentid);

            if (cluster.isEmpty()) {
                return ResponseCode.EXIST_NOT;
            }

            parent = cluster.getList(WebNode.PARENT, new ArrayList());
            parent.add(cluster.get(WebNode.ID));
            webNode.put(WebNode.PARENT_ID, cluster.get(WebNode.ID));
        }

        String id = webNode.setId();
        webNode.put(WebNode.PARENT, parent);
        webNode.put(WebNode.DEEP, parent.size());
        webNode.put(WebNode.CREATED, new Date());
        webNodeDAO.insert(webNode);
        return ResponseCode.FINISH;
    }

    public int update(KeyUpdate keyUpdate) throws Exception {
        int result = ResponseCode.FINISH;

        if ("PARENT_ID".equals(keyUpdate.getName())) {
            result = updateParent(keyUpdate);
        } else {
            webNodeDAO.update(keyUpdate);
        }

        return result;
    }

    private int updateParent(KeyUpdate keyUpdate) {
        Cluster webNode = webNodeDAO.findById(keyUpdate.getId());
        String parentId = keyUpdate.getValue();
        List oldParentList = webNode.getList(WebNode.PARENT, new ArrayList());
        List newParentList;

        if (parentId == null || "".equals(parentId)) {
            newParentList = new ArrayList();
            webNode.remove(WebNode.PARENT_ID);
        } else {
            Cluster parent = webNodeDAO.findById(parentId);
            if (parent.isEmpty()) {
                return ResponseCode.EXIST_NOT;
            }
            newParentList = parent.getList(WebNode.PARENT, new ArrayList());
            newParentList.add(parent.get(WebNode.ID));
            webNode.put(WebNode.PARENT_ID, parent.get(WebNode.ID));
        }

        webNode.put(WebNode.PARENT, newParentList);
        webNodeDAO.save(webNode);
        updateChildren(webNode, oldParentList, newParentList);
        return ResponseCode.FINISH;
    }

    private void updateChildren(Cluster webNode, List oldParentList, List newParentList) {
        Query query = new Query();
        query.eq(WebNode.PARENT, webNode.get(WebNode.ID));
        Update update = new Update();
        update.pullAll(WebNode.PARENT, oldParentList);
        update.push(WebNode.PARENT, newParentList, null, 0);
        webNodeDAO.update(query, update, false, true);
    }

    public List parent(String id) {
        ObjectId objectId = new ObjectId(id);
        Query query = new Query();
        query.ne(WebNode.PARENT, objectId);
        query.ne(WebNode.ID, objectId);
        Field field = new Field();
        field.include(WebNode.ID, WebNode.NAME, WebNode.PARENT_ID);
        List webNodes = webNodeDAO.find(query, field, null);
        return webNodes;
    }

    public int remove(List<String> ids) {
        Query query = new Query();
        query.idIn(ids);
        webNodeDAO.remove(query);
        return ResponseCode.FINISH;
    }
}
